package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.po.PointsRecord;
import com.tianji.learning.domain.query.QuestionPageQuery;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.enums.PointsRecordType;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    @Autowired
    private RabbitMqHelper rabbitMqHelper;

    //发布问题
    @Override
    public void saveQuestion(QuestionFormDTO questionFormDTO) {
        //1. dto->po
        InteractionQuestion question = BeanUtil.copyProperties(questionFormDTO, InteractionQuestion.class);
        //2. 补充属性(其他属性有默认值)
        question.setUserId(UserContext.getUser());
        //3.保存数据库
        this.save(question);
        //4. 发送MQ消息，新增积分
        PointsRecord pointsRecord = new PointsRecord();
        pointsRecord.setUserId(UserContext.getUser());
        pointsRecord.setType(PointsRecordType.QA);
        pointsRecord.setPoints(5);
        rabbitMqHelper.send(
                MqConstants.Exchange.LEARNING_EXCHANGE,
                MqConstants.Key.WRITE_REPLY,
                pointsRecord
        );


    }



    @Autowired
    private IInteractionReplyService replyService;

    @Autowired
    private UserClient userClient;

    //1.分页查询问题
    //2.根据最新回答id批量查询回答信息，转为Map集合
    //3.根据提问者id+回答者id批量查寻用户信息，转为Map集合
    //4.遍历问题集合，封装QuestionVO
    //5.返回结果
    // 分页问题列表
    @Override
    public PageDTO<QuestionVO> userQuestionPage(QuestionPageQuery query) {
        //1. 分页查询问题
        //1-1 分页
        Page<InteractionQuestion> page = new Page<>(query.getPageNo(), query.getPageSize());
        //1-2条件查询
        Boolean onlyMine = query.getOnlyMine();//是否只查我的
        Long courseId = query.getCourseId();//课程id
        Long sectionId = query.getSectionId();//章节id
        this.lambdaQuery()
                .eq(onlyMine,InteractionQuestion::getUserId,UserContext.getUser())
                .eq(courseId != null,InteractionQuestion::getCourseId,courseId)
                .eq(sectionId != null,InteractionQuestion::getSectionId,sectionId)
                .orderByDesc(InteractionQuestion::getUpdateTime)
                .page(page);
        //1-3 如果没有问题列表返回空对象
        List<InteractionQuestion> questionList = page.getRecords();
        if(CollUtil.isEmpty(questionList)){
            return PageDTO.empty(page);
        }
        //2. 根据最新回答id批量查询回答信息，转为Map集合 比如一个小节下有10个问题 都把这10个问题 对应的最新回答表查询出来
        Set<Long> answerIdSet = questionList.stream().map(InteractionQuestion::getLatestAnswerId).collect(Collectors.toSet());
        //2-2 查询回答表
        List<InteractionReply> replyList = replyService.listByIds(answerIdSet);
        //2-3 转map集合
        Map<Long, InteractionReply> replyMap = replyList.stream().collect(Collectors.toMap(InteractionReply::getId, reply -> reply));
        //2-4 获取回答用户id集合
        Set<Long> replyUserIdSet = replyList.stream().map(InteractionReply::getUserId).collect(Collectors.toSet());
        //3. 根据提问者id+回答者id批量查询用户信息，转为Map集合
        //3-1 获取提问者id集合
        Set<Long> questionUserIdSet = questionList.stream().map(InteractionQuestion::getUserId).collect(Collectors.toSet());
        //3-2 回答用户id
        questionUserIdSet.addAll(replyUserIdSet);
        //3-3 feign远程调用
        List<UserDTO> userDTOList = userClient.queryUserByIds(questionUserIdSet);
        //3-4 转map集合
        Map<Long, UserDTO> userDTOMap = userDTOList.stream().collect(Collectors.toMap(UserDTO::getId, user -> user));
        //4.遍历问题集合，封装QuestionVO
        ArrayList<QuestionVO> voList = new ArrayList<>(questionList.size());
        for (InteractionQuestion question : questionList) {
            //4-1 po->vo
            QuestionVO questionVO = BeanUtil.copyProperties(question, QuestionVO.class);
            //4-2 补充提问者信息(不是匿名)
            if(!question.getAnonymity()){
                UserDTO userDTO = userDTOMap.get(question.getUserId());
                questionVO.setUserName(userDTO.getName());//提问人名称
                questionVO.setUserIcon(userDTO.getIcon());//提问人头像
            }
            //4-3补充回答用户昵称和内容 (如果有)
            if(question.getLatestAnswerId() != null){
                InteractionReply reply = replyMap.get(question.getLatestAnswerId());
                // 如果不是匿名就显示用户昵称
                if(!reply.getAnonymity()){
                    String replyUser = userDTOMap.get(reply.getUserId()).getName();
                    questionVO.setLatestReplyUser(replyUser);
                }else {
                    questionVO.setLatestReplyUser("匿名");
                }
                //回答的内容
                questionVO.setLatestReplyContent(reply.getContent());
            }
            //4-4 添加到voList
            voList.add(questionVO);
        }
        //5. 返回结果
        return PageDTO.of(page,voList);
    }

    //1. 根据id查询问题
    //2. 封装QuestionVO
    //3. 返回结果
    @Override
    public QuestionVO findQuestionById(Long id) {
        //1. 根据id查询问题
        InteractionQuestion question = this.getById(id);
        if(question == null || question.getHidden()){
            return null;
        }
        //2. 封装QuestionVO
        QuestionVO questionVO = BeanUtil.copyProperties(question, QuestionVO.class);
        if(!questionVO.getAnonymity()){//不匿名，才查询用户信息
            UserDTO userDTO = userClient.queryUserById(question.getUserId());
            questionVO.setUserName(userDTO.getName());
            questionVO.setUserIcon(userDTO.getIcon());
        }
        //3. 结果返回
        return questionVO;
    }
}
